package com.m1.tzolkin.model.buildables;

import java.util.HashMap;
import java.util.Map;

import com.m1.tzolkin.model.Action;
import com.m1.tzolkin.model.IAction;
import com.m1.tzolkin.model.ITZStock;
import com.m1.tzolkin.model.TZResource;
import com.m1.tzolkin.model.TZStock;
import com.m1.tzolkin.model.TzolkinConstants;
import com.m1.tzolkin.model.board.ITZBoard;
import com.m1.tzolkin.model.exceptions.NoAvailableSkullException;
import com.m1.tzolkin.model.exceptions.StepMoveException;
import com.m1.tzolkin.model.players.ITZPlayer;
import com.m1.tzolkin.model.technos.Technologies;
import com.m1.tzolkin.model.temples.TempleEnum;
import com.m1.tzolkin.model.wheels.IWheel;
import com.m1.tzolkin.model.wheels.WheelEnum;

public enum ActionBuildingTypes implements TzolkinConstants {
	
	// ZONE 1
	
	BUILDING_1(BuildableType.CIVIL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = -8459657501039101424L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			b.upTech(Technologies.RESOURCE_EXTRACTION, p);
			p.addCorn(1);
			b.getLog().addSentence(new String[] {
				p.getName(), "EARN", "1", "CORN"
			});
		}
	}, new TZStock()
			.addResource(TZResource.WOOD)
			.addResource(TZResource.STONE)
	),
	BUILDING_2(BuildableType.CIVIL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = -5872820931325468216L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			b.upTech(Technologies.AGRICULTURE, p);
			p.getWallet().addResource(TZResource.STONE);
			b.getLog().addSentence(new String[] {
				p.getName(), "EARN", "1", "WOOD"
			});
		}
	}, new TZStock()
			.addResource(TZResource.WOOD, 3)
	),
	BUILDING_3(BuildableType.FUNERAL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = -7223291807125528650L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setUpTemples(1);
			b.setBuildBuildings(1);
		}
	}, new TZStock()
			.addResource(TZResource.WOOD)
			.addResource(TZResource.GOLD)
	),
	BUILDING_4(BuildableType.FUNERAL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1144585074124388733L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			try {
				b.upTemple(p, TempleEnum.CHAAC);
			} catch (StepMoveException e) { /* Rien */ }
			try {
				b.upTemple(p, TempleEnum.KUKULCAN);
			} catch (StepMoveException e) { /* Rien */ }
		}
	}, new TZStock()
			.addResource(TZResource.WOOD)
			.addResource(TZResource.STONE, 2)
	),
	BUILDING_5(BuildableType.SACRED, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = -3107667171576790142L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.upTech(Technologies.THEOLOGY, p);
			try {
				b.upTemple(p, TempleEnum.KUKULCAN);
			} catch (StepMoveException e) { /* Rien */ }
		}
	}, new TZStock()
			.addResource(TZResource.STONE)
			.addResource(TZResource.GOLD)
	),
	BUILDING_6(BuildableType.CIVIL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 3392282257280854722L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			b.upTech(Technologies.RESOURCE_EXTRACTION, p);
			p.getWallet().addResource(TZResource.GOLD);
			b.getLog().addSentence(new String[] {
				p.getName(), "EARN", "1", "GOLD"
			});
		}
	}, new TZStock()
			.addResource(TZResource.WOOD, 2)
			.addResource(TZResource.STONE)
	),
	BUILDING_7(BuildableType.SACRED, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = -7300011878178395871L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			b.upTech(Technologies.ARCHITECTURE, p);
		}
	}, new TZStock()
			.addResource(TZResource.GOLD)
	),
	BUILDING_8(BuildableType.FUNERAL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = -3160338339021467295L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			try {
				b.upTemple(p, TempleEnum.CHAAC);
			} catch (StepMoveException e) { /* Rien */ }
			try {
				b.upTemple(p, TempleEnum.QUETZALCOATL);
			} catch (StepMoveException e) { /* Rien */ }
		}
	}, new TZStock()
			.addResource(TZResource.WOOD, 2)
			.addResource(TZResource.STONE)
	),
	BUILDING_9(BuildableType.CIVIL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 5214128980229338922L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			b.upTech(Technologies.AGRICULTURE, p);
		}
	}, new TZStock()
			.addResource(TZResource.WOOD, 2)
	),
	
	// ZONE 2
	
	BUILDING_10(BuildableType.CIVIL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = -8473001777571303983L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			try {
				b.getBank().takeSkull();
				p.getWallet().addSkull();
				b.getLog().addSentence(new String[] {
					p.getName(), "GET", "1", "SKULL"
				});
			} catch (NoAvailableSkullException e) {/* Rien */ }
		}
	}, new TZStock()
			.addResource(TZResource.WOOD, 2)
			.addResource(TZResource.STONE, 2)
	),
	BUILDING_11(BuildableType.FUNERAL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 511322766825984371L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			try {
				b.upTemple(p, TempleEnum.CHAAC);
			} catch (StepMoveException e) { /* Rien */ }
			try {
				b.upTemple(p, TempleEnum.QUETZALCOATL);
			} catch (StepMoveException e) { /* Rien */ }
			try {
				b.upTemple(p, TempleEnum.KUKULCAN);
			} catch (StepMoveException e) { /* Rien */ }
			p.addScore(3);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "3", "POINTS"
			});
		}
	}, new TZStock()
			.addResource(TZResource.WOOD)
			.addResource(TZResource.STONE, 2)
			.addResource(TZResource.GOLD)
	),
	BUILDING_12(BuildableType.SACRED, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 492558031637737896L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			try {
				b.upTemple(p, TempleEnum.KUKULCAN);
				b.upTemple(p, TempleEnum.KUKULCAN);
			} catch (StepMoveException e) { /* Rien */ }
			p.addScore(3);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "3", "POINTS"
			});
		}
	}, new TZStock()
			.addResource(TZResource.GOLD, 2)
	),
	BUILDING_13(BuildableType.FUNERAL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 3177540138198869135L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			int cost = 1;
			if (p.getCorn() >= cost) {
				Map<IAction, Integer> act = new HashMap<IAction, Integer>();
				for (WheelEnum w : WheelEnum.values()) {
					IWheel wheel = b.getWheel(w);
					if (!wheel.isForbidden()) {
						for (IAction a : wheel.getActions()) {
							act.put(a, cost);
						}
					}
				}
				b.setActions(act);
			}
			p.addScore(2);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "2", "POINTS"
			});
		}
	}, new TZStock()
			.addResource(TZResource.WOOD, 2)
			.addResource(TZResource.STONE)
			.addResource(TZResource.GOLD)
	),
	BUILDING_14(BuildableType.FUNERAL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = -1226261207739767424L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			if (p.getTotalPawns().size() < MAX_WORKERS) {
				p.addPawn();
				b.getLog().addSentence(new String[] {
					p.getName(), "GET", "1", "WORKER"
				});
			}
			p.addScore(6);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "3", "POINTS"
			});
		}
	}, new TZStock()
			.addResource(TZResource.WOOD)
			.addResource(TZResource.STONE)
			.addResource(TZResource.GOLD)
	),
	BUILDING_15(BuildableType.SACRED, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 739682935901497L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(2, false);
		}
	}, new TZStock()
			.addResource(TZResource.STONE)
			.addResource(TZResource.GOLD, 2)
	),
	BUILDING_16(BuildableType.FUNERAL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 5104802809233084724L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			p.addScore(8);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "8", "POINTS"
			});
		}
	}, new TZStock()
			.addResource(TZResource.WOOD)
			.addResource(TZResource.GOLD, 2)
	),
	BUILDING_17(BuildableType.SACRED, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 4290797304018267054L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			try {
				b.upTemple(p, TempleEnum.CHAAC);
				b.upTemple(p, TempleEnum.CHAAC);
			} catch (StepMoveException e) { /* Rien */ }
			p.addScore(2);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "2", "POINTS"
			});
		}
	}, new TZStock()
			.addResource(TZResource.STONE, 2)
	),
	BUILDING_18(BuildableType.CIVIL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 4809335569974874848L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			p.getWallet().addResource(TZResource.STONE);
			b.getLog().addSentence(new String[] {
				p.getName(), "EARN", "1", "ROCK"
			});
		}
	}, new TZStock()
			.addResource(TZResource.WOOD, 3)
	),
	BUILDING_19(BuildableType.SACRED, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = -8149094674285309977L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			b.upTech(Technologies.THEOLOGY, p);
			try {
				b.upTemple(p, TempleEnum.CHAAC);
			} catch (StepMoveException e) { /* Rien */ }
			try {
				b.upTemple(p, TempleEnum.KUKULCAN);
			} catch (StepMoveException e) { /* Rien */ }
		}
	}, new TZStock()
			.addResource(TZResource.STONE, 2)
			.addResource(TZResource.GOLD)
	),
	BUILDING_20(BuildableType.SACRED, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 2304994141345169342L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			try {
				b.upTemple(p, TempleEnum.QUETZALCOATL);
				b.upTemple(p, TempleEnum.QUETZALCOATL);
			} catch (StepMoveException e) { /* Rien */ }
			p.addScore(4);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "4", "POINTS"
			});
		}
	}, new TZStock()
			.addResource(TZResource.GOLD, 3)
	),
	BUILDING_21(BuildableType.FUNERAL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 5896117504240453520L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setExchange(true);
			p.addScore(6);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "6", "POINTS"
			});
		}
	}, new TZStock()
			.addResource(TZResource.STONE, 3)
	),
	BUILDING_22(BuildableType.CIVIL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 8586685696771574478L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			p.addCorn(6);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "6", "POINTS"
			});
		}
	}, new TZStock()
			.addResource(TZResource.WOOD, 3)
			.addResource(TZResource.STONE)
	),
	BUILDING_23(BuildableType.CIVIL, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = 4335600032713120867L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			p.getWallet().addResource(TZResource.WOOD);
			b.getLog().addSentence(new String[] {
				p.getName(), "EARN", "1", "WOOD"
			});
		}
	}, new TZStock()
			.addResource(TZResource.WOOD, 2)
			.addResource(TZResource.STONE)
	),
	BUILDING_24(BuildableType.SACRED, new Action() {
		/**
		 * 
		 */
		private static final long serialVersionUID = -7090873671293223220L;

		public void doAction(ITZBoard b, ITZPlayer p) {
			b.setTechEvolve(1, false);
			b.upTech(Technologies.ARCHITECTURE, p);
			p.addScore(3);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "3", "POINTS"
			});
		}
	}, new TZStock()
			.addResource(TZResource.STONE)
			.addResource(TZResource.GOLD)
	);
	
	// ATTRIBUTS
	
	private final BuildableType type;
	private final IAction action;
	private final ITZStock cost;
	
	// CONSTRUCTEUR
	
	private ActionBuildingTypes(BuildableType type, IAction action, ITZStock cost) {
		this.type = type;
		this.action = action;
		this.cost = cost;
	}
	
	// REQUETES
	
	BuildableType getType() {
		return type;
	}
	
	IAction getAction() {
		return action;
	}
	
	ITZStock getCost() {
		return cost;
	}
	
}
